package com.ly.heart.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.ly.common.core.domain.AjaxResult;
import com.ly.common.exception.CustomException;
import com.ly.common.utils.DateUtils;
import com.ly.common.utils.SecurityUtils;
import com.ly.common.utils.StringUtils;
import com.ly.common.utils.erp.ConstUtil;
import com.ly.common.utils.erp.SnowflakeIdWorker;
import com.ly.heart.mapper.KingDocTypeMapper;
import com.ly.heart.service.IKingDocTypeService;
import com.ly.heart.util.ChineseToPinyin;
import com.ly.heart.util.CurrentUserUtil;
import org.springframework.stereotype.Service;
import com.ly.heart.domain.KingDocTypeEntity;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;

/**
 * 金蝶-财务模块-单据类型Service业务层处理
 *
 * @author wutao
 * @date 2024-06-24
 */
@Service
public class KingDocTypeServiceImpl extends ServiceImpl<KingDocTypeMapper, KingDocTypeEntity> implements IKingDocTypeService {

    @Resource
    private KingDocTypeMapper kingDocTypeEntityMapper;

    /**
     * 查询金蝶-财务模块-单据类型
     *
     * @param id 金蝶-财务模块-单据类型ID
     * @return 金蝶-财务模块-单据类型
     */
    @Override
    public KingDocTypeEntity selectKingDocTypeEntityById ( String id ) {
        return kingDocTypeEntityMapper.selectKingDocTypeEntityById ( id );
    }

    /**
     * 查询金蝶-财务模块-单据类型列表
     *
     * @param kingDocTypeEntity 金蝶-财务模块-单据类型
     * @return 金蝶-财务模块-单据类型
     */
    @Override
    public List<KingDocTypeEntity> selectKingDocTypeEntityList ( KingDocTypeEntity kingDocTypeEntity ) {
        //查询一二级菜单列表，组装
        List<Integer> levels = new ArrayList<> ();
        levels.add ( 1 );
        levels.add ( 2 );
        List<KingDocTypeEntity> menus = this.list ( new QueryWrapper<KingDocTypeEntity> ().in ( "level", levels ) );
        List<KingDocTypeEntity> firstMenus = menus.stream ().filter ( m -> "ALL".equals ( m.getParentCode () ) ).collect ( Collectors.toList () );
        for ( KingDocTypeEntity m : firstMenus ) {
            m.setTreeList ( getChild ( m.getDocCode (), menus ) );
        }
        return firstMenus;
    }


    /**
     * 查询单据类型三级Table，通过一级和二级都可以查询
     *
     * @param kingDocTypeEntity
     * @return
     */
    @Override
    public List<KingDocTypeEntity> queryTable ( KingDocTypeEntity kingDocTypeEntity ) {
        if ( kingDocTypeEntity == null || StringUtils.isBlank ( kingDocTypeEntity.getDocCode () ) ) {
            throw new RuntimeException ( "父级编码为空" );
        }
        KingDocTypeEntity docTypeEntity = this.query ().eq ( "doc_code", kingDocTypeEntity.getDocCode () ).one ();
        if ( docTypeEntity == null ) {
            throw new RuntimeException ( "该父级编码已失效" );
        }
        //递归获取子Table
        kingDocTypeEntity.setPage ( ( kingDocTypeEntity.getPage () - 1 ) * kingDocTypeEntity.getLimit () );
        List<KingDocTypeEntity> kingDocTypeEntities = kingDocTypeEntityMapper.queryTable ( kingDocTypeEntity );
        return kingDocTypeEntities;
    }

    @Override
    public Integer queryCount ( KingDocTypeEntity kingDocTypeEntity ) {
        Integer count = kingDocTypeEntityMapper.queryCount ( kingDocTypeEntity );
        return count;
    }

    /**
     * 查询单据类型列表
     *
     * @param kingDocTypeEntity
     * @return
     */
    @Override
    public List<KingDocTypeEntity> queryChild ( KingDocTypeEntity kingDocTypeEntity ) {
        if ( ObjectUtils.isEmpty ( kingDocTypeEntity ) ) {
            throw new RuntimeException ( "请求对象为空" );
        }
        if ( StringUtils.isEmpty ( kingDocTypeEntity.getParentCode () ) ) {
            throw new RuntimeException ( "请求对象parentCode为空" );
        }
        List<KingDocTypeEntity> parentEntities = this.query ().eq ( "parent_code", kingDocTypeEntity.getParentCode () ).list ();
        return parentEntities;
    }

    /**
     * 新增金蝶-财务模块-单据类型
     *
     * @param kingDocTypeEntity 金蝶-财务模块-单据类型
     * @return 结果
     */
    @Override
    public AjaxResult insertKingDocTypeEntity ( KingDocTypeEntity kingDocTypeEntity ) {
        kingDocTypeEntity.setId ( SnowflakeIdWorker.getInstance ().nextStringId () );
        //先拿到一级单据名字
        if ( StringUtils.isBlank ( kingDocTypeEntity.getParentCode () ) ) {
            throw new RuntimeException ( "父级单据不能为空" );
        }
        KingDocTypeEntity parentDoc = this.getOne ( new QueryWrapper<KingDocTypeEntity> ().eq ( "doc_code", kingDocTypeEntity.getParentCode () ) );
        //处理docCode=父单据名称首字母拼接8位数字递增
        String parentPy = ChineseToPinyin.getFirstLetter ( parentDoc.getTitle () );
        int count = this.count ( new QueryWrapper<KingDocTypeEntity> ().eq ( "parent_code", parentDoc.getDocCode () ) );
        String countStr = String.format ( "%08d", count );
        kingDocTypeEntity.setDocCode ( parentPy.concat ( countStr ) );
        String docTypePy = ChineseToPinyin.getFirstLetter ( kingDocTypeEntity.getTitle () );
        //拼接规则：父级首字母_单据类型首字母
        kingDocTypeEntity.setKeyCode ( parentPy.concat ( "_" ).concat ( docTypePy ) );
        kingDocTypeEntity.setLevel ( parentDoc.getLevel () + 1 );
        kingDocTypeEntity.setDeptId ( CurrentUserUtil.getCompanyId () );
        kingDocTypeEntity.setCreateBy ( SecurityUtils.getLoginUser ().getUser ().getUserId () );
        kingDocTypeEntity.setCreateTime ( DateUtils.getNowDate () );
        boolean save = this.save ( kingDocTypeEntity );
        if ( ! save ) {
            throw new CustomException ( "新增单据类型失败！" );
        }
        return AjaxResult.success ();
    }

    /**
     * 修改金蝶-财务模块-单据类型
     *
     * @param kingDocTypeEntity 金蝶-财务模块-单据类型
     * @return 结果
     */
    @Override
    public AjaxResult updateKingDocTypeEntity ( KingDocTypeEntity kingDocTypeEntity ) {
        kingDocTypeEntity.setUpdateBy ( SecurityUtils.getLoginUser ().getUser ().getUserId () );
        kingDocTypeEntity.setUpdateTime ( DateUtils.getNowDate () );
        boolean b = this.updateById ( kingDocTypeEntity );
        if ( ! b ) {
            throw new CustomException ( "修改单据类型失败！" );
        }
        return AjaxResult.success ();
    }

    /**
     * 批量删除金蝶-财务模块-单据类型
     *
     * @param ids 需要删除的金蝶-财务模块-单据类型ID
     * @return 结果
     */
    @Override
    public AjaxResult deleteKingDocTypeEntityByIds ( String[] ids ) {
        boolean update = this.update ( new LambdaUpdateWrapper<KingDocTypeEntity> ().set ( KingDocTypeEntity :: getIsUsed, ConstUtil.IS_USED_NO ).
                set ( KingDocTypeEntity :: getUpdateBy, SecurityUtils.getLoginUser ().getUser ().getUserId () ).
                set ( KingDocTypeEntity :: getUpdateTime, DateUtils.getNowDate () ).
                in ( KingDocTypeEntity :: getId, ids ) );
        if ( ! update ) {
            throw new CustomException ( "删除单据类型失败！" );
        }
        return AjaxResult.success ();
    }

    /**
     * 删除金蝶-财务模块-单据类型信息
     *
     * @param id 金蝶-财务模块-单据类型ID
     * @return 结果
     */
    @Override
    public AjaxResult disabled ( String id ) {
        KingDocTypeEntity docTypeEntity = this.getById ( id );
        boolean update = this.update ( new LambdaUpdateWrapper<KingDocTypeEntity> ().set ( KingDocTypeEntity :: getIsDisabled, docTypeEntity.getIsDisabled () == 1 ? 2 : 1 ).
                set ( KingDocTypeEntity :: getUpdateBy, SecurityUtils.getLoginUser ().getUser ().getUserId () ).
                set ( KingDocTypeEntity :: getUpdateTime, DateUtils.getNowDate () ).
                eq ( KingDocTypeEntity :: getId, id ) );
        if ( ! update ) {
            throw new CustomException ( docTypeEntity.getIsDisabled () == 1 ? "禁用单据类型失败！" : "解禁单据类型失败！" );
        }
        return AjaxResult.success ();
    }

    /**
     * 递归查找子菜单
     *
     * @param docCode  当前菜单id
     * @param rootList 要查找的列表
     * @return
     */
    private List<KingDocTypeEntity> getChild ( String docCode, List<KingDocTypeEntity> rootList ) {
        //子级
        List<KingDocTypeEntity> childList = new ArrayList<> ();
        for ( KingDocTypeEntity menuInfo : rootList ) {
            // 遍历所有节点，将父级id与传过来的id比较
            if ( menuInfo.getParentCode ().equals ( docCode ) ) {
                childList.add ( menuInfo );
            }
        }
        // 把子级的子级再循环一遍
        for ( KingDocTypeEntity sonMenuInfo : childList ) {
            sonMenuInfo.setTreeList ( getChild ( sonMenuInfo.getDocCode (), rootList ) );
        }
        // 递归退出条件
        if ( childList.isEmpty () ) {
            return null;
        }
        return childList;
    }

}
